Multi-Stage Builds
マルチステージビルド
stageというある程度まとまった単位でプログラムをビルドする
コンテナのサイズを軽量にできる
build成果物に必要十分なものだけを含められる
docs
#wip
https://zenn.dev/hakshu/articles/docker-multi-stage-build
Dockerfile内に、複数のDockerfile: FROMを記述する
各FROMから新しいbuild stageが始まる
FROM .. AS ..でstageに名前をつけられる
COPY --from=hogeみたいにして、別stageの成果物を参照できる
Dockerfile: COPY --from
例 ref
code:Dockerfile
FROM golang:1.16 AS builder
WORKDIR /hoge/piyo/
RUN ...
COPY ...
RUN ...
FROM alpine:latest
RUN ...
WORKDIR ...
COPY --from=builder /hoge/piyo/app ./ # builderからcopy
CMD ...
GPT-4.icon
例
Rust で Web API(Actix Web など)をビルドして、最小限のイメージにデプロイする例を考えてみましょう。
code:dockerfile
# 1. ビルドステージ (Rustコンパイラなどを含む)
FROM rust:1.75 AS build-stage
WORKDIR /app
COPY Cargo.toml Cargo.lock ./
RUN cargo fetch # 依存関係を事前に取得
COPY src ./src
RUN cargo build --release
# 2. 本番環境ステージ (最小限のランタイム)
FROM debian:bullseye-slim AS prod-stage
WORKDIR /app
# build-stage からバイナリのみをコピー (コンパイラなどは不要)
COPY --from=build-stage /app/target/release/myapp .
# 実行
CMD "./myapp"
build-stage
アプリケーションをビルドするためのステージ
rust:1.75 イメージ → 約 2GB
prod-stage
最終的な軽量な本番環境のイメージを作成する
rustc, cargoなどは不要で、最小限のランタイム (glibc など) のみを内包する
セキュリティ面でも好ましい
debian:bullseye-slim イメージ → 約 22MB
https://docs.docker.jp/develop/develop-images/dockerfile_best-practices.html#id9